#pragma once
#include <typescommon.h>

#pragma pack(1)
enum protocolParseCommonStepEnum
{
    protocolParseCommonStep_FixedHead = 0,
    protocolParseCommonStep_Version,
    protocolParseCommonStep_AllHead,
    protocolParseCommonStep_Data,
};
enum protocolParseCommonVersionEnum
{
    protocolParseCommonVersion0 = 0,
    protocolParseCommonVersion1,
    protocolParseCommonVersion2,
    protocolParseCommonVersion3,
};
enum protocolParseCrypteTypeEnum
{
    protocolParseCrypte_None = 0,
    protocolParseCrypte_Aes,
    protocolParseCrypte_Rsa,
    protocolParseCrypte_SM4,
    protocolParseCrypte_SM2,
    protocolParseCrypte_Des3,
    //
};
#define PROTOCOL_FIXED_HEAD_SIZE 3
struct protocolVersion0
{ // V0
    uint32_t v0DataSize;
    uint8_t v0Data[1];
};
struct protocolVersion1
{                               // V1
    uint32_t v1DataSize;        // 数据长度
    uint8_t v1DataCrypteType;   // 加密类型
    uint8_t v1DataCompressType; // 压缩标志
    uint8_t v1DataType;         // 0:结构体，1：json
    uint8_t v1Crc;              // 求和校验
    uint8_t v1Data[1];
};
struct protocolVersion2
{                               // V2
    uint16_t v2DataSize;        // 数据长度
    uint8_t v2SourceAddr;       // 源地址
    uint8_t v2DestinationAddr;  // 目标地址，无需解密就知道是不是本设备数据。
    uint8_t v2DataCrypteType;   // 加密类型
    uint8_t v2DataCompressType; // 压缩标志
    uint8_t v2DataType;         // 0:结构体，1：json
    uint8_t v2Crc;              // 求和校验
    uint8_t v2Data[1];
};
struct protocolVersion3
{                               // V2
    uint16_t v3DataSize;        // 数据长度
    uint8_t v3Remain1;
    uint8_t v3Remain2;
    uint8_t v3DesAddr[DEVICE_SERIAL_NUMBER_SIZE];  // 目标地址
    uint8_t v3CrypteType;   // 加密类型
    uint8_t v3Crc;              // 求和校验
    uint8_t v3Data[1];
};
struct protocolPackageCommonInform
{
    struct
    {
        uint8_t protocolFixedHead[PROTOCOL_FIXED_HEAD_SIZE]; // 固定0XC6B796
        uint8_t protocolVersion;                             // 协议版本
    };
    union
    {
        struct protocolVersion0 v0;
        struct protocolVersion1 v1;
        struct protocolVersion2 pv2;
        struct protocolVersion3 v3;
    };
};
#pragma pack()

typedef void (*protocolParseCallback)(void *packdata, uint32_t packsize, void *userdata);
struct protocolPackageParseInform
{
    union
    {
        struct protocolPackageCommonInform *packinform;
        uint8_t *packbuffer;
    };
    uint32_t parseMaxPackSize;           // parse receive max size
    int parseState;
    uint32_t parseReceiveSize;           // receive count
    uint32_t parseHeadSize;              // calculate head size
    uint32_t parseTotalSize;             // calculate package total size
    protocolParseCallback parseCallback; // parse ok and callback
};

int protocolPackageParseInit(struct protocolPackageParseInform *parseinform, protocolParseCallback setCallback,
                             void *setpack, uint32_t setMaxPackageSize);
uint32_t protocolPackageDataV0(const void *packData, uint32_t packsize, void *outPack, uint32_t outsize);
uint32_t protocolPackageDataV1(const void *packData, uint32_t packsize, void *outPack, uint32_t outsize,
                               uint8_t packCrypteType, uint8_t packCompressType, uint8_t packDataType);
uint16_t protocolPackageDataV2(void *outPack, uint16_t outsize);
uint16_t protocolPackageDataV3(void *outPack, uint16_t outsize);
void protocolPackageParseValue(struct protocolPackageParseInform *parseinform, uint8_t indata);
